from datetime import datetime
import json
import os
import subprocess
from bs4 import BeautifulSoup
from weasyprint import HTML
from jinja2 import Template

import requests
from flask import Flask, render_template, send_from_directory, request, send_file

from funasr import AutoModel
from funasr.utils.postprocess_utils import rich_transcription_postprocess

from soundfile import read

model = AutoModel(
    model="flaskProject/SenseVoiceSmall",
    trust_remote_code=False,
    device="cuda:0",
    disable_update=True,
)


def modelsc():
    print('开始!')
    path = "flaskProject/static/model/imcs21-cblue-main/task3/t5/test/test_input.json"
    while not os.path.exists(path):
        pass
    cmd1 = "cd flaskProject/static/model/imcs21-cblue-main/task3/t5"
    cmd2 = "python transform.py"
    cmd3 = "python predict_with_generate.py --test_data ./test/predict.tsv --result_file ./test/predict_result.tsv --use_multiprocess"
    cmd4 = "cd .."
    cmd5 = "python postprocess.py --gold_path t5/test/test_input.json --pred_path t5/test/predict_result.tsv --target t5"
    cmd = cmd1 + " && " + cmd2 + " && " + cmd3 + " && " + cmd4 + " && " + cmd5
    # 如下两种都可以运行
    subprocess.Popen(cmd, shell=True)
    # subprocess.call(cmd, shell=True)
    print('完成!')


app = Flask(__name__)


@app.route('/')
def hello():
    return render_template('html/hello.html')


@app.route('/recognition', methods=['GET', 'POST'])
def recognition():
    return render_template('html/recognition.html')


@app.route('/patient', methods=['GET', 'POST'])
def patient():
    return render_template('html/patient.html')


@app.route('/result')
def result():  # 诊断结果
    user_name = request.args.get('user_name')
    user_id = request.args.get('user_id')
    return render_template('html/result.html', user_name=user_name,user_id=user_id)


@app.route('/data_return', methods=['GET', 'POST'])
def data_return():
    json_get = request.args
    dialogues = []
    dialogue = {
        'sentence_id': "",
        'speaker': "",
        'sentence': ""
    }
    selfReportText = ""
    user = ""
    n = 0
    for i in json_get:
        if i == 'id1[self-report]':
            selfReportText = json_get[i]
        elif i == 'id1[user]':
            user = json_get[i]
        else:
            n += 1
            if n % 3 == 1:
                dialogue['sentence_id'] = json_get[i]
            elif n % 3 == 2:
                dialogue['speaker'] = json_get[i]
            else:
                dialogue['sentence'] = json_get[i]
                dialogues.append(dialogue.copy())
    json_data = {
        "id1": {
            "self_report": selfReportText,
            "dialogue": dialogues,
        }}
    print(json_data)

    user_name = 1

    file_name = "output"
    file_path = 'flaskProject/static/temporary/' + file_name + str(user_name) + '.txt'

    while os.path.exists(file_path):
        user_name += 1
        file_path = 'flaskProject/static/temporary/' + file_name + str(user_name) + '.txt'

    with open(file_path, 'w', encoding='utf-8') as f:
        f.write(
            json.dumps(
                json_data,
                indent=4,
                ensure_ascii=False))

    with open('flaskProject/static/model/imcs21-cblue-main/task3/t5/test/test_input.json', 'w', encoding='utf-8') as f:
        f.write(
            json.dumps(
                json_data,
                indent=4,
                ensure_ascii=False))
    modelsc()

    os.remove(file_path)

    if user == 'patient':
        file_path = 'flaskProject/static/model/imcs21-cblue-main/task3/t5/test/test_input.json'
    else:
        file_path = 'flaskProject/static/model/imcs21-cblue-main/task3/t5/test/predict_result.json'

    # 打开文件
    with open(file_path, 'r', encoding='utf-8') as file:
        # 读取文件内容
        content = file.read()

    url = "https://spark-api-open.xf-yun.com/v1/chat/completions"
    data = {"max_tokens": 4096, "top_k": 4, "temperature": 0.5, "messages": [
        {
            "role": "system",
            "content": "你是一个专业的医疗助手,我会提供一份辅助诊断报告，你根据报告提供可能的疾病列表和相关应对措施"
        },
        {
            "role": "user",
            "content": content,
        }
    ], "model": "4.0Ultra", "stream": True}
    header = {
        "Authorization": "Bearer rhTBRuhEnIlHLCepeROP:frUFOhMGMQlFpNVEiFtl"
    }
    response = requests.post(url, headers=header, json=data, stream=True)

    # 流式响应解析示例
    response.encoding = "utf-8"

    full_content = ""  # 存储所有content的字符串

    for line in response.iter_lines(decode_unicode="utf-8"):
        if line:  # 确保该行不为空
            line_str = line.strip()
            if line_str.startswith("data: "):
                # 去掉"data: "前缀，提取有效JSON部分
                json_data_str = line_str[6:]
                try:
                    # 将字符串转换为JSON
                    json_data = json.loads(json_data_str)

                    # 检查并提取content
                    if "choices" in json_data:
                        delta = json_data["choices"][0].get("delta", {})
                        content = delta.get("content", "")
                        if content != " ":
                            full_content += content  # 累加content
                except json.JSONDecodeError:
                    if line == "data: [DONE]":
                        break
                    else:
                        print("无法解析为JSON:", line_str)

    print(full_content)

    file_path = 'flaskProject/static/temporary/output'+str(user_name)+'.txt'
    with open(file_path, 'w', encoding='utf-8') as file:
        file.write(full_content)

    return {"success": user_name}


@app.route('/speech_return', methods=['GET', 'POST'])
def speech_return():
    # 检查请求中是否包含文件
    if 'upfile' not in request.files:
        return {"error": "No file part"}

    file = request.files['upfile']

    # 检查文件名是否为空
    if file.filename == '':
        return {"error": "No selected file"}

    file_name = file.filename.rsplit('.', 1)[0]
    i = 1
    file_path = 'flaskProject/uploads/' + file_name + str(i) + '.mp3'
    while os.path.exists(file_path):
        i += 1
        file_path = 'flaskProject/uploads/' + file_name + str(i) + '.mp3'

    # 保存文件到服务器
    file.save(f"{file_path}")

    res = model.generate(
        input=file_path,
        # 音频路径
        cache={},
        language="zn",
        # "zn", "en", "yue", "ja", "ko", "nospeech"
        use_itn=True,
        batch_size=64,
    )
    text = rich_transcription_postprocess(res[0]["text"])
    print(text)
    os.remove(file_path)
    return {"success": text}

@app.route('/pdf_download', methods=['GET', 'POST'])
def pdf_download():
    json_get = request.args
    pd = -1
    list = []
    for i in json_get:
        if pd == -1:
            pd = i
        list.append(json_get[i])
        # print(json_get[i])

    # 获取当前日期和时间
    now = datetime.now()
    # 格式化日期和时间，去除微秒部分
    formatted_time = now.strftime("%Y-%m-%d %H:%M:%S")

    if pd == '1':
        with open("flaskProject/templates/html/Auxiliary diagnostic report.html", "r", encoding="utf-8") as file:
            html_template = file.read()
        # 创建 Jinja2 模板
        template = Template(html_template)
        # 渲染模板并设置变量的值
        rendered_html = template.render(generation_time=formatted_time,main_suit=list[0],history_illness=list[1],auxiliary_examination=list[2],past_history=list[3],diagnosis=list[4],suggestion=list[5])
        html = HTML(string=rendered_html)
        i = 1
        pdf_path = 'uploads/Auxiliary diagnostic report' + str(i) + '.pdf'
        while os.path.exists("flaskProject/" + pdf_path):
            i += 1
            pdf_path = 'uploads/Auxiliary diagnostic report' + str(i) + '.pdf'
    else:
        with open("flaskProject/templates/html/List of related diseases.html", "r", encoding="utf-8") as file:
            html_template = file.read()
        # 创建 Jinja2 模板
        template = Template(html_template)
        # 渲染模板并设置变量的值
        rendered_html = template.render(generation_time=formatted_time)
        soup = BeautifulSoup(rendered_html, 'lxml')
        # 找到具有特定类名的 <table> 元素
        table = soup.find('table', class_='table-left-3-right-7')
        for i in list:
            # 创建一个新的 <tr> 元素
            new_tr = soup.new_tag('tr')
            parts1 = i.split("-  ", 1)
            if len(parts1) == 1:
                # 创建新的 <th> 和 <td> 元素，并添加到 <tr> 中
                new_th = soup.new_tag('th')
                new_th.string = ''
                new_td = soup.new_tag('td')
                new_td.string = parts1[0]
            else :
                parts2 = parts1[1].split("：", 1)
                # 创建新的 <th> 和 <td> 元素，并添加到 <tr> 中
                new_th = soup.new_tag('th')
                new_th.string = parts2[0]
                new_td = soup.new_tag('td')
                new_td.string = parts2[1]

            new_tr.append(new_th)
            new_tr.append(new_td)
            # 将新的 <tr> 添加到 <table> 中
            if table:
                table.append(new_tr)

        html = HTML(string=soup.prettify())
        i = 1
        pdf_path = 'uploads/List of related diseases.pdf' + str(i) + '.pdf'
        while os.path.exists("flaskProject/" + pdf_path):
            i += 1
            pdf_path = 'uploads/Auxiliary diagnostic report' + str(i) + '.pdf'

    html.write_pdf("flaskProject/" + pdf_path)
    return send_file(pdf_path, as_attachment=True, mimetype='application/pdf')

@app.route('/favicon.ico')
def favicon():
    return send_from_directory(os.path.join(app.root_path, 'static'), 'favicon.ico',
                               mimetype='image/vnd.microsoft.icon')


if __name__ == '__main__':
    app.run(debug=True)
